<?php
namespace service\express\sources;

use artisan\cache as Redis;
use artisan\db;

/**
 * 获取快递查询数据源配置
 */
class DataSource
{
    /**
     * db instance
     *
     * @var null
     */
    protected static $db = null;

    /**
     * db source
     *
     * @var string
     */
    protected static $db_name = 'express';

    /**
     * table name
     *
     * @var string
     */
    protected static $source_table = 'express_data_source';

    /**
     * cache ttl
     *
     * @var integer
     */
    protected $cache_ttl = 3600;

    /**
     * error infos
     *
     * @var array
     */
    private $error = [];

    // 'SELECT express_brand,brand_name,data_source,status,priority FROM express_data_sources WHERE status = 1 GROUP BY express_brand,data_source ORDER BY priority ASC';

    /**
     * getSource
     *
     * @param  array|null $condtion
     * @return array
     */
    public function getSource(array $condtion = null, $renew = false)
    {
        $key = 'express_data_source:' . __FUNCTION__ . (is_array($condtion) ? md5(json_encode($condtion)) : '');
        if ($renew || !$data = Redis::get($key)) {
            $data = $this->getAllSource(['status >' => 0], null, 'priority ASC');
            Redis::set($key, serialize($data), $this->cache_ttl);
        }
        return is_array($data) ? $data : unserialize($data);
    }

    /**
     * getOldTypeSource
     *
     * @return array
     */
    public function getOldTypeSource($renew = false)
    {
        $key = 'express_data_source:' . __FUNCTION__;
        if ($renew || !$data = Redis::get($key)) {
            $data = $this->getAllSource(['status >' => 0], null, 'priority ASC', 'express_brand,data_source');
            if ($data = $this->convertSourceToOldStructure($data)) {
                Redis::set($key, serialize($data), $this->cache_ttl);
            }
        }
        return is_array($data) ? $data : unserialize($data);
    }

    /**
     * convertSourceToOldStructure
     *
     * @param  array $data
     * @return array
     */
    private function convertSourceToOldStructure(array $data = [])
    {
        $result = [];
        $other = [];
        foreach ($data as $key => $val) {
            !isset($result[$val['express_brand']]) and $result[$val['express_brand']] = $val['express_brand'] . '_' . $val['data_source']; //$val['source'];
            // if(!isset($result[$val['express_brand']])){
            //     $result[$val['express_brand']] = $val['express_brand'] . '_' . $val['data_source']; //$val['source'];
            // }else{
            //     isset($other[$val['express_brand']]) ? $other[$val['express_brand']] .= $val['data_source'] : $other[$val['express_brand']] = $val['data_source'];
            // }
        }
        return $result;
    }

    /**
     * get all express data source
     *
     * @param array $condition
     * @return array|boolean
     */
    private function getAllSource(array $condition = [], $limit = null, $order = 'priority DESC', $group_by = '')
    {
        $condition = [
            'status' => 1,
        ];
        //因为select的解析无法用concat(express_data_source,'_',data_source)
        if (($data = static::getDB()->select('express_brand,brand_name,data_source,status,priority')->groupBy($group_by)->getAll($condition, $limit, $order)) && is_array($data)) {
            return $this->sources = $data;
        } else {
            $this->error[] = static::getDB()->lastQuery();
            $this->error[] = static::getDB()->getLastError();
        }
        return false;
    }

    /**
     * get a db instance
     *
     * @return \artisan\db;
     */
    private static function getDB($table = '')
    {
        if (static::$db === null) {
            static::$db = db::connect(static::$db_name);
        }
        return static::$db->table($table ?: static::$source_table);
    }

    /**
     * @return array
     */
    public function getError()
    {
        return $this->error;
    }
}
